<?php
/**
 * 短信接口
 * Created by PhpStorm.
 * User: tiemeng
 * Date: 15/9/21
 * Time: 11:46
 */

class sms {
    protected $_testinUrl = 'http://api.sms.testin.cn/sms'; //云测url地址
    protected $_chanzorUrl = 'http://sms.chanzor.com:8001/sms.aspx'; //畅卓url地址
    protected $_wtUrl = 'http://wt.3tong.net/json/sms/Submit'; //大汉三通
    protected $_hdUrl = 'http://118.178.189.133/msg/HttpSendSM?';//航动通信科技
    protected $_secretKey = '3F9D18EE75F67169';//云测字符串密钥
    protected $_redisPrefix = 'HupuRun_';

    //云平台请求参数
    protected $_testinConfig = array(
        'apiKey'     => 'fff61070c9e0e40470c9ba64c7e5bf1e',
        'op'         => 'Sms.send',
        'templateId' => '1097',
        'ts'         => '',
        'phone'      => '',
        'content'    => '您的验证码是：%d。该验证码10分钟内有效！请不要泄露给其他人',
    );

    //畅卓请求参数
    protected $_chanzor = array(
        'action'     => 'send',
        'userid'     => '',
        'account'    => 'kcs8551',
        'password'   => '152177',
        'mobile'     => '',
        'sendTime'   => '',
        'content'    => "",
    );

    //大汉三通请求参数
    protected $_wt = array(
        'account'    => 'dh25631',  //账号
        'password'   => '0LEz9!$H',  //密码
        'msgid'      => '',  //短信编号
        'phones'     => '',
        'content'    => '您的验证码是：%d。该验证码10分钟内有效！请不要泄露给其他人',
        'sign'       => '【虎扑跑步】',  //短信签名
        'subcode'    => '',  //短信字码
        'sendtime'   => ''
    );

    //航动请求参数
    protected $_hdConfig = array(
        'account'    => 'pudong',  //账号
        'pswd'   => '8em2yh6T4y',  //密码
        'mobile'      => '',  //手机号
        'msg'     => '您的验证码是：%d。该验证码10分钟内有效！请不要泄露给其他人',
        'needstatus'    => false,
        'product'       => 16611,  //产品ID
        'extno'    => 728  //扩展码，最多可以扩展6位
    );

    public function __construct(){
        $environment = ENVIRONMENT;
        $this->config = config::$$environment;
        $this->redis = new mredis($this->config['redis']['ip'], $this->config['redis']['port']);
    }


    /**
     * 大汉三通短信发送
     * @access public
     * @param $phone
     * @param $client
     * @return bool
     */
    public function wtSMS($phone,$client){
        $t = isset($_COOKIE['t']) ? $_COOKIE['t'] : '';
        if(empty($phone) || !preg_match('/^1\d{10}$/',$phone) || !empty($t))
        {
            return false;
        }
        if(!$this->_checkCount($phone,$client))
            return -1;
        $verifyCode = mt_rand(1021,9999);
        $this->_wt['password'] = md5($this->_wt['password']);
        $this->_wt['phones'] = $phone;
        $this->_wt['content'] = sprintf($this->_wt['content'],$verifyCode);
        $param = json_encode($this->_wt);
        $res = $this->_postRquest($this->_wtUrl,$param);
        $reData = json_decode($res,true);
        if($reData['result'] === 0 && empty($reData['failPhones']))
        {
            $cookVal = md5($this->_secretKey.$verifyCode);
            setcookie('c',$cookVal,time()+600);//十分钟内有效
            setcookie('t','done',time()+60);//设置发送完成的值,一分钟内只能请求一次
            return true;
        }
        return false;
    }

    /**
     * 云测平台短信发送 ---已废弃
     * @access public
     * @param $phone 手机号码
     * @return bool
     */
    public function testinSMS($phone,$client)
    {
        $t = isset($_COOKIE['t']) ? $_COOKIE['t'] : '';
        if(empty($phone))
        {
            return false;
        }

        if(!empty($t))
        {
            return -2;
        }

        if(!$this->_checkCount($phone,$client)){
            return -1;
        }
        $verifyCode = mt_rand(1021,9999);
        $this->_testinConfig['ts'] = floor((microtime(true)*1000));
        $this->_testinConfig['phone'] = $phone;
        $this->_testinConfig['content'] = sprintf($this->_wt['content'],$verifyCode);
        $params = $this->_queryData();
        $res = $this->_postRquest($this->_testinUrl,$params);
        $arr = json_decode($res,true);
        if($arr['code'] == 1000)
        {
            $cookVal = md5($this->_secretKey.$verifyCode);
            setcookie('c',$cookVal,time()+600);//十分钟内有效
            setcookie('t','done',time()+50);//设置发送完成的值,一分钟内只能请求一次
            return 1000;
        }
        return $arr['code'];
    }

    /**
     * 云测平台短信发送
     * @param 手机号码
     * @param $verifyCode 验证码
     * @param int $flag  1 找回密码 0 更改手机、注册和手机绑定……(预留字段 以后最好区分业务)
     * @return bool
     */
    public function testinSMSNew($phone, $verifyCode, $flag=0)
    {
        if(empty($phone) || empty($verifyCode)) {
            return false;
        }
        $this->_testinConfig['ts'] = floor((microtime(true)*1000));
        $this->_testinConfig['phone'] = $phone;
        $this->_testinConfig['content'] = sprintf($this->_wt['content'],$verifyCode);
        $params = $this->_queryData();
        $res = $this->_postRquest($this->_testinUrl,$params);
        $arr = json_decode($res,true);
        return $arr['code'];
    }

    /**
     * 用户年终数据发送接口
     * @param $phone
     * @param $verifyCode
     * @param int $flag
     * @return bool
     */
    public function testinSMSNewYear($phone, $alphaId)
    {
        if(empty($phone) || empty($alphaId)) {
            return false;
        }
        $_wt = array(
            'account'    => 'dh25631',  //账号
            'password'   => '0LEz9!$H',  //密码
            'msgid'      => '',  //短信编号
            'phones'     => '',
            'content'    => '您的2016运动报告已生成，快来看看自己多厉害。点我领取>http://irun.hupu.com/show/yearEnd?uid=%s',
            'sign'       => '【虎扑跑步】',  //短信签名
            'subcode'    => '',  //短信字码
            'sendtime'   => ''
        );
        $this->_testinConfig['ts'] = floor((microtime(true)*1000));
        $this->_testinConfig['phone'] = $phone;
        $this->_testinConfig['content'] = sprintf($_wt['content'],$alphaId);
        $params = $this->_queryData();
        $res = $this->_postRquest($this->_testinUrl,$params);
        $arr = json_decode($res,true);
        return $arr['code'];
    }

    /**
     * 航动平台短信发送
     * @param 手机号码
     * @param $verifyCode 验证码
     * @param int $flag  1 找回密码 0 更改手机、注册和手机绑定……(预留字段 以后最好区分业务)
     * @return bool
     */
    public function hdSMSNew($phone, $verifyCode, $flag=0)
    {
        if(empty($phone) || empty($verifyCode)) {
            return false;
        }
        $this->_hdConfig['mobile'] = $phone;
        $this->_hdConfig['msg'] = '【虎扑跑步】+'.sprintf($this->_hdConfig['msg'],$verifyCode);
        $o = "";
        foreach ($this->_hdConfig as $k=>$v) {
            $o.= "$k=".urlencode($v)."&";
        }
        $params = substr($o, 0, -1);
        $res = $this->_postRquest($this->_hdUrl,$params);
        $resultCode = '';
        if ($res) {
           $arrResult = explode(',', $res);
            if(isset($arrResult[1]) &&  $arrResult[1] === '0') {
                $resultCode =1000;
            }
        }
        return $resultCode;
    }

    /**
     * 畅卓平台短信发送
     * @access public
     * @param $phone
     * @return bool
     */
    public function chanzorSMS($phone,$client)
    {
        $t = isset($_COOKIE['t']) ? $_COOKIE['t'] : '';
        if(empty($phone) || !empty($t))
        {
            return false;
        }
        if(!$this->_checkCount($phone,$client))
            return -1;
        $verifyCode = mt_rand(1021,9999);
        $this->_chanzor['mobile'] = $phone;
        $this->_chanzor['content'] = "您的验证码为：".$verifyCode.",10分钟内有效。为了保护您的账号安全请不要泄露给他人【虎扑跑步】";
        $queryStr = http_build_query($this->_chanzor);
        $res = $this->_postRquest($this->_chanzorUrl,$queryStr);
        $start=strpos($res,"<?xml");
        $data=substr($res,$start);
        $xml=simplexml_load_string($data);
        $arr = json_decode(json_encode($xml),true);
        if($arr['returnstatus'] == 'Success')
        {
            $cookVal = md5($this->_secretKey.$verifyCode);
            setcookie('c',$cookVal,time()+600);//十分钟内有效
            setcookie('t','done',time()+50);//设置发送完成的值,一分钟内只能请求一次
            return true;
        }
        return false;

    }


    /**
     * 验证码校验----已废除
     * @access public
     * @param $str
     * @return bool
     */
    public function chekcode($str)
    {
        $code = isset($_COOKIE['c']) ? $_COOKIE['c'] : '';
        $inputCode = md5($this->_secretKey.$str);
        if(empty($code)){
            return 1004;
        }
        if($code != $inputCode){
            return 1102;
        }

        if( $code == $inputCode ){
            setcookie('c');
            setcookie('t');
            return true;
        }
    }

    /**
     * 查询短信剩余条数
     * @return mixed
     */
    public function banlance(){
        list($s1, $s2) = explode(' ', microtime());
        $time = (float)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000);
        $param = array(
            'apiKey'     => 'fff61070c9e0e40470c9ba64c7e5bf1e',
            'op'         => 'Sms.account',
            'ts'         => $time,
        );
        $params = $this->_queryData($param);

       // $smsNumber = $this->redis->get(REDIS_PREFIX.'TextStatistics');
       // if(!$smsNumber)
       // {
            $result = $this->_postRquest($this->_testinUrl,$params);
         //   $this->redis->set(REDIS_PREFIX.'TextStatistics', $result);
          //  $this->redis->expire(REDIS_PREFIX.'TextStatistics',300);

        //}
        // else
        // {
        //     $result = $smsNumber;
        // }

        return $result;
    }

    /**
     * 生成请求参数及签名
     * @access protected
     * @return string
     */
    protected function _queryData($param='')
    {
        if(!empty($param)){
            $this->_testinConfig = $param;
        }
        $signure = '';
        ksort($this->_testinConfig);
        foreach($this->_testinConfig as $key=>$val)
        {
            $signure .= $key.'='.$val;
        }
        $signure .= $this->_secretKey;
        $this->_testinConfig['sig'] = md5($signure);
        return json_encode($this->_testinConfig);
    }

    /**
     * 向服务器请求数据
     * @access protected
     * @param $params
     * @return mixed
     */
    protected function _postRquest($url,$params)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL,$url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_VERBOSE, '1');
        $user_agent = "Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)";
        curl_setopt($ch, CURLOPT_POSTFIELDS,$params);
        curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($ch, CURLOPT_TIMEOUT, 25);
        $return = curl_exec($ch);
        curl_close($ch);
        return $return;
    }

    /**
     * 一个账号在5小时内只能请求5次，超过5次，锁定5小时
     * @param $phone
     * @param $client
     * @return bool
     */
    private function _checkCount($phone,$client){
        $ip = common::getip(true);
        $ipKey = $this->_redisPrefix.'ip'.$ip;
        $phoneKey = $this->_redisPrefix.'phone'.$phone;
        $clientKey = $this->_redisPrefix.'client'.$client;
        $forbidKey = $this->_redisPrefix."forbid".$phone;
        if($this->redis->get($forbidKey)){
            return false;
        }
        $ipCount = intval($this->redis->get($ipKey));
        $phoneCount = intval($this->redis->get($phoneKey));
        $clientCount = intval($this->redis->get($clientKey));
        if($ipCount >= 5 || $phoneCount >= 5 || $clientCount >= 5){
            $this->redis->setex($forbidKey,5*3600,1);
            return false;

        }
        if(!$this->redis->exists($phoneKey)){
            $time = 5*3600;
            $this->redis->setex($ipKey,$time,1);
            $this->redis->setex($phoneKey,$time,1);
            $this->redis->setex($clientKey,$time,1);
        }else{
            $this->redis->incr($ipKey);
            $this->redis->incr($phoneKey);
            $this->redis->incr($clientKey);
        }

        return true;
    }

}